using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using s8rfdll;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        const int CARD_4442 = 42;
        const int CARD_4428 = 28;
        private Int32  gl_hdev = (Int32 )(-1);
        private string gl_strmsg;
        private byte gl_offset_42 = 32;
        private int gl_len_42 = 16;
        private byte gl_offset_28 = 32;
        private int gl_len_28 = 16;

        public Form1()
        {
            InitializeComponent();
        }
        private void getSerial(ref int port, ref int baud)
        {
            port = cmbb_port.SelectedIndex;
            baud = Convert.ToInt32(cmbb_baud.Text);
        }

        private int getCurrentCardType()
        {
            int[] cardInsertStatus = new int[2];
            int st;

            if (-1 == gl_hdev)
                return 0;

            st = PubClass.fw_rdCardStatus(gl_hdev, cardInsertStatus);
            if (st == 0 && cardInsertStatus[0] == 0)
            {
                printMsg("No card insert.");
                return 0;
            }

         
            if (radioButton1.Checked)
                return CARD_4442;
            if (radioButton2.Checked)
                return CARD_4428;

            return 0;
        }
        private void printMsg(string str)
        {
            str += "\r\n";
            gl_strmsg += str;

            textBox1.Text = gl_strmsg;
            textBox1.Focus();
            textBox1.Select(textBox1.Text.Length - str.Length, str.Length);
            textBox1.ScrollToCaret();
        }

        private void clearMsg()
        {
            gl_strmsg = "";
            textBox1.Text = "";
        }

        /// <summary> 
        /// Button Click - Read
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_read_Click(object sender, EventArgs e)
        {
            Int32  st;
            byte[] errCount = new byte[2];
            byte[] rData = new byte[1024];
            string strmsg;
            int i;

            clearMsg();

            switch (getCurrentCardType())
            {
                case CARD_4442:
                    {//==============4442/5542 ===

                        ////Read check count remaind
                        PubClass.fw_cntReadError_4442(gl_hdev, errCount);
                        if (errCount[0] == 0)
                        {
                            printMsg("Invalid card -- Check wrong password over max times.");
                            return;
                        }
                        printMsg("Remaind error count:" + errCount[0].ToString());


                        //read data
                        st = PubClass.fw_read_4442(gl_hdev, gl_offset_42,  rData, gl_len_42);
                        if (st != 0)
                        {
                            printMsg("ERROR: Read failed!");
                            return;
                        }

                        printMsg("Read Ok.");

                        strmsg = "Hex string:";
                        for (i = 0; i < gl_len_42; i++)
                            strmsg += rData[i].ToString("X2") + " ";

                        printMsg(strmsg);

                        printMsg("ASC:" + System.Text.Encoding.ASCII.GetString(rData, 0, gl_len_42));

                    }
                    break;
                case CARD_4428:
                    {////==============4428/5528 ===


                        //Read check count remaind 
                        PubClass.fw_cntReadError_4428(gl_hdev, errCount);
                        if (errCount[0] == 0)
                        {
                            printMsg("Invalid card -- Check wrong password over max times.");
                            return;
                        }

                        printMsg("Remaind error count:" + errCount[0].ToString());


                        st = PubClass.fw_read_4428(gl_hdev, gl_offset_28, rData, gl_len_28);
                        if (st != 0)
                        {
                            printMsg("ERROR: Read failed!");
                            return;
                        }

                        printMsg("Read Ok.");

                        strmsg = "Hex string:";
                        for (i = 0; i < gl_len_28; i++)
                            strmsg += rData[i].ToString("X2") + " ";

                        printMsg(strmsg);

                        printMsg("ASC:" + System.Text.Encoding.ASCII.GetString(rData, 0, gl_len_28));

                    }
                    break;
            }

        }
        /// <summary>
        /// Button Click - Write
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_write_Click(object sender, EventArgs e)
        {
            Int32 st;
            byte[] errCount = new byte[2];
            byte[] Init28pwd = new byte[] { 0xff, 0xff };
            byte[] Init42pwd = new byte[] { 0xff, 0xff, 0xff };
            byte[] wData = new byte[1024];
            int i;

            clearMsg();

            switch (getCurrentCardType())
            {
                case CARD_4442:
                    {//==============4442/5542 ===

                        //check card password
                        st = PubClass.fw_authentikey_4442(gl_hdev, 0, 3, Init42pwd);
                        if (st != 0)
                        {
                            printMsg("Invalid card -- Check wrong password over max times.");
                            return;
                        }

                        
                        ////Read check count remaind
                        PubClass.fw_cntReadError_4442(gl_hdev, errCount);
                        if (errCount[0] == 0)
                        {
                            printMsg("Get error count remaind failed.");
                            return;
                        }
                        printMsg("Remaind error count:" + errCount[0].ToString());
                        

                        //write data

                        for (i = 0; i < gl_len_42; i++)
                            wData[i] = Convert.ToByte(i + 0x31);// or Convert.ToByte(i + '1');

                        st = PubClass.fw_write_4442(gl_hdev, gl_offset_42, wData, gl_len_42);
                        if (st != 0)
                        {
                            printMsg("ERROR: Write failed!");
                            return;
                        }

                        printMsg("Write Ok.");

                    }
                    break;
                case CARD_4428:
                    {////==============4428/5528 ===


                        //check initial card password (ffff)
                        st = PubClass.fw_authentikey_4428(gl_hdev,  Init28pwd);
                        if (st != 0)
                        {
                            printMsg("Check 4428 Password failed.");
                            return;
                        }


                        printMsg("Check Password: " + Init28pwd[0].ToString("X") + Init28pwd[1].ToString("X") + " ok.");

                        
                        //Read check count remaind 
                        PubClass.fw_cntReadError_4428(gl_hdev, errCount);
                        if (errCount[0] == 0)
                        {
                            printMsg("Invalid card -- Check wrong password over max times.");
                            return;
                        }

                        printMsg("Remaind error count:" + errCount[0].ToString());
                        

                        for (i = 0; i < gl_len_28; i++)
                            wData[i] = Convert.ToByte(i + 0x31);// or Convert.ToByte(i + '1');

                        st = PubClass.fw_write_4428(gl_hdev, gl_offset_28, wData, gl_len_28);
                        if (st != 0)
                        {
                            printMsg("ERROR: Write failed!");
                            return;
                        }

                        printMsg("Write Ok.");

                    }
                    break;
            }


        }

        /// <summary>
        /// Button Click - Proection Bit Test
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_protect_Click(object sender, EventArgs e)
        {
            Int32 st;
            byte[] errCount = new byte[2];
            byte[] Init28pwd = new byte[] { 0xff, 0xff };
            byte[] Init42pwd = new byte[] { 0xff, 0xff, 0xff };
            byte[] rData = new byte[1024];
            byte[] wData = new byte[1024];
            int i;
            byte offset_prot_42 = 6;
            int len_prot_42 = 2;
            int len_prot_28 = 1;


            clearMsg();

            switch (getCurrentCardType())
            {
                case CARD_4442:
                    {//==============4442/5542 ===

                        //check card password
                        st = PubClass.fw_authentikey_4442(gl_hdev, 0, 3, Init42pwd);
                        if (st != 0)
                        {
                            printMsg("Invalid card -- Check wrong password over max times.");
                            return;
                        }


                        ////Read check count remaind
                        PubClass.fw_cntReadError_4442(gl_hdev, errCount);
                        if (errCount[0] == 0)
                        {
                            printMsg("Get error count remaind failed.");
                            return;
                        }
                        printMsg("Remaind error count:" + errCount[0].ToString());

                        //Read protect data
                        st = PubClass.fw_getProtectData_4442(gl_hdev, offset_prot_42, rData, len_prot_42);

                        //write protect data
                        wData[0] = Convert.ToByte(0x81);
                        wData[1] = Convert.ToByte(0x15);

                        PubClass.fw_write_4442(gl_hdev, offset_prot_42, wData, len_prot_42);//this call is nesssory

                        st = PubClass.fw_setProtectData_4442(gl_hdev, offset_prot_42, wData, len_prot_42);
                        if (st != 0)
                        {
                            printMsg("ERROR: Write failed!");
                            return;
                        }

                        printMsg("Write Ok.");

                    }
                    break;
                case CARD_4428:
                    {////==============4428/5528 ===

                        //check initial card password (ffff)
                        st = PubClass.fw_authentikey_4428(gl_hdev,  Init28pwd);
                        if (st != 0)
                        {
                            printMsg("Check 4428 Password failed.");
                            return;
                        }


                        printMsg("Check Password: " + Init28pwd[0].ToString("X") + Init28pwd[1].ToString("X") + " ok.");


                        //Read check count remaind 
                        PubClass.fw_cntReadError_4428(gl_hdev, errCount);
                        if (errCount[0] == 0)
                        {
                            printMsg("Invalid card -- Check wrong password over max times.");
                            return;
                        }

                        printMsg("Remaind error count:" + errCount[0].ToString());

                        st = PubClass.fw_getProtectData_4428(gl_hdev, rData, len_prot_28);


                        for (i = 0; i < len_prot_28 ; i++)
                            wData[i] = Convert.ToByte(i + 0x31);// or Convert.ToByte(i + '1');

                        st = PubClass.fw_setProtectData_4428(gl_hdev, wData, len_prot_28);
                        if (st != 0)
                        {
                            printMsg("ERROR: Write failed!");
                            return;
                        }

                        printMsg("Write Ok.");

                    }
                    break;
            }
        }

        /// <summary>
        /// Button Click - Password Change test
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_ChangePwd_Click(object sender, EventArgs e)
        {
            Int32 st;
            byte[] errCount = new byte[2];
            byte[] Init28pwd = new byte[] { 0xff, 0xff };
            byte[] Init42pwd = new byte[] { 0xff, 0xff, 0xff };

            clearMsg();

            switch (getCurrentCardType())
            {
                case CARD_4442:
                    {//==============4442/5542 ===

                        //check card password
                        st = PubClass.fw_authentikey_4442(gl_hdev, 0, 3, Init42pwd);
                        if (st != 0)
                        {
                            printMsg("Invalid card -- Check wrong password over max times.");
                            return;
                        }


                        ////Read check count remaind
                        PubClass.fw_cntReadError_4442(gl_hdev, errCount);
                        if (errCount[0] == 0)
                        {
                            printMsg("Get error count remaind failed.");
                            return;
                        }
                        printMsg("Remaind error count:" + errCount[0].ToString());


                        st = PubClass.fw_changkey_4442(gl_hdev, 0, 3, Init42pwd);
                        if (st != 0)
                        {
                            printMsg("ERROR: Change passowrd failed!");
                            return;
                        }

                        printMsg("Change passowrd Ok.");

                    }
                    break;
                case CARD_4428:
                    {////==============4428/5528 ===

                        //check initial card password (ffff)
                        st = PubClass.fw_authentikey_4428(gl_hdev, Init28pwd);
                        if (st != 0)
                        {
                            printMsg("Check 4428 Password failed.");
                            return;
                        }


                        printMsg("Check Password: " + Init28pwd[0].ToString("X") + Init28pwd[1].ToString("X") + " ok.");


                        //Read check count remaind 
                        PubClass.fw_cntReadError_4428(gl_hdev, errCount);
                        if (errCount[0] == 0)
                        {
                            printMsg("Invalid card -- Check wrong password over max times.");
                            return;
                        }

                        printMsg("Remaind error count:" + errCount[0].ToString());

                        st = PubClass.fw_changkey_4428(gl_hdev,  Init28pwd);
                        if (st != 0)
                        {
                            printMsg("ERROR: Change passowrd failed!");
                            return;
                        }

                        printMsg("Change passowrd Ok.");

                    }
                    break;
            }
        }

        /// <summary>
        /// Button Click - Open port
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Open_Click(object sender, EventArgs e)
        {
            int _port = 0, _baud = 0;

            if (rdoBtn_USB.Checked)
            {
                gl_hdev = PubClass.fw_init(100, 0);
            }
            else
            {
                getSerial(ref _port, ref  _baud);
                gl_hdev = PubClass.fw_init((short)_port, _baud);
            }

            if ((-1) == gl_hdev)
            {
                printMsg("Open device error.");
            }
            else
            {
                printMsg("Open device ok.");

                btn_read.Enabled = true;
                btn_write.Enabled = true;
                btn_protect.Enabled = true;
                btn_ChangePwd.Enabled = true;
                btn_Open.Enabled = false;
                btn_Close.Enabled = true;
            }

        }

        /// <summary>
        /// Button Click - Close port
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Close_Click(object sender, EventArgs e)
        {
            if (gl_hdev != (-1))
            {
                PubClass.fw_exit(gl_hdev);
                printMsg("Device Closed.");

                btn_read.Enabled = false;
                btn_write.Enabled = false;
                btn_protect.Enabled = false;
                btn_ChangePwd.Enabled = false;
                btn_Open.Enabled = true;
                btn_Close.Enabled = false;
            }
            else
                printMsg("Device is not opened.");

        }
        /// <summary>
        /// Button Click - Clear text
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Clear_Click(object sender, EventArgs e)
        {
            clearMsg();
        }

        /// <summary>
        /// Load Form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            cmbb_port.SelectedIndex = 0;
            cmbb_baud.SelectedIndex = 0;
        }
    }
}
